package io.gitee.thinkbungee.crud.mongo.bean;

import io.gitee.thinkbungee.crud.mongo.reflection.SerializableFunction;
import io.gitee.thinkbungee.crud.mongo.utils.FunctionResolveUtils;
import org.springframework.data.domain.Sort;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 排序类
 *
 * @author chenyichang
 * @date 2022/5/12
 */
public class SortBuilder {

    protected List<Sort.Order> orderList = new ArrayList<>();

    public SortBuilder() {
    }

    public SortBuilder(List<Sort.Order> orderList) {
        this.orderList.addAll(orderList);
    }

    public <T, R> SortBuilder(SerializableFunction<T, R> column, Sort.Direction direction) {
        Sort.Order order = new Sort.Order(direction, FunctionResolveUtils.resolve(column));
        orderList.add(order);
    }

    public SortBuilder(String column, Sort.Direction direction) {
        Sort.Order order = new Sort.Order(direction, column);
        orderList.add(order);
    }


    /**
     * 返回排序
     */
    public Sort build() {
        return Sort.by(orderList);
    }

    /**
     * 添加某个字段的排序
     *
     * @param column    字段
     * @param direction 排序方式
     * @param <T>       参数泛型
     * @param <R>       返回泛型
     */
    public <T, R> SortBuilder add(SerializableFunction<T, R> column, Sort.Direction direction) {
        orderList.add(new Sort.Order(direction, FunctionResolveUtils.resolve(column)));
        return this;
    }

    public SortBuilder add(String column, Sort.Direction direction) {
        orderList.add(new Sort.Order(direction, column));
        return this;
    }

    //==================排序==================//
    private static SortBuilder asc(String column) {
        return new SortBuilder().add(column, Sort.Direction.ASC);
    }

    private static SortBuilder desc(String column) {
        return new SortBuilder().add(column, Sort.Direction.DESC);
    }

    public static List<SortBuilder> ascs(String[] orderColumns) {
        return Arrays.stream(orderColumns).map(SortBuilder::asc).collect(Collectors.toList());
    }

    public static List<SortBuilder> descs(String[] orderColumns) {
        return Arrays.stream(orderColumns).map(SortBuilder::desc).collect(Collectors.toList());
    }

}
